﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using AvalonDock;
using Genetic.Data;
using Genetic.Data.IO;
using Genetic.Properties;
using Genetic.SystemPresenter;
using Genetic.SystemPresenter.Content;
using Microsoft.Win32;

namespace Genetic
{
    public partial class frmTableEditor : DocumentContent, IContentForm, IDocumentForm
    {
        public TableData Data;
        public string File;
        public string DataPath { get; private set; }

        readonly bool _isBINI;

        readonly UndoManager<ChangedData> _undoManager = new UndoManager<ChangedData>();

        public ViewerType ViewerType { get; set; }
        public ArchetypeManager Archetype { get; set; }

        public delegate void DataChangedType(ChangedData data);

        public DataChangedType DataChanged;

        public delegate void SelectionChangedType(ObservableCollection<TableBlock> data, int templateIndex);

        public SelectionChangedType SelectionChanged;

        public delegate void DataVisibilityChangedType(TableBlock block);

        public DataVisibilityChangedType DataVisibilityChanged;

        public delegate void ContentChangedType(IContentForm content);

        public ContentChangedType ContentChanged;

        public delegate void DocumentChangedType(IDocumentForm document);

        public DocumentChangedType DocumentChanged;

        void OnDataChanged(ChangedData data)
        {
            if (DataChanged != null)
            {
                DataChanged(data);
            }
        }

        void OnSelectionChanged(ObservableCollection<TableBlock> data, int templateIndex)
        {
            if (SelectionChanged != null)
            {
                SelectionChanged(data, templateIndex);
            }
        }

        void OnDataVisibilityChanged(TableBlock block)
        {
            if (DataVisibilityChanged != null)
            {
                DataVisibilityChanged(block);
            }
        }

        void OnContentChanged(IContentForm content)
        {
            if (ContentChanged != null)
            {
                ContentChanged(content);
            }
        }

        void OnDocumentChanged(IDocumentForm document)
        {
            if (DocumentChanged != null)
            {
                DocumentChanged(document);
            }
        }

        public frmTableEditor(int templateIndex, string file)
        {
            InitializeComponent();

            _undoManager.DataChanged += UndoManager_DataChanged;

            if (file != null)
            {
                FileManager fileManager = new FileManager(file);
                EditorINIData iniContent = fileManager.Read(FileEncoding.Automatic, templateIndex);

                Data = new TableData(iniContent);
                _isBINI = fileManager.IsBINI;

                SetFile(file);
            }
            else
            {
                Data = new TableData
                    {
                        TemplateIndex = templateIndex
                    };

                SetFile(string.Empty);
            }
        }

        string ShowSolarArchetypeSelector()
        {
            OpenFileDialog openFile = new OpenFileDialog
                {
                    Title = string.Format(Strings.FileEditorOpenSolarArch, GetFileName()),
                    Filter = "Solar Archetype INI|*.ini"
                };
            if (openFile.ShowDialog().Value)
            {
                return openFile.FileName;
            }

            return null;
        }

        void LoadArchetypes()
        {
            string archetypeFile = ArchetypeManager.GetRelativeArchetype(File, Data.TemplateIndex);

            //user interaction required to get the path of the archetype file
            if (archetypeFile == null)
            {
                archetypeFile = ShowSolarArchetypeSelector();
            }

            //set data path based on archetype file and not system file
            DataPath = Helper.Template.Data.GetDataPath(archetypeFile, Helper.Template.Data.SolarArchetypeFile);

            if (Archetype == null)
            {
                Archetype = new ArchetypeManager(archetypeFile, Helper.Template.Data.SolarArchetypeFile);
            }

            SetAllBlockTypes();
        }

        void SetAllBlockTypes()
        {
            foreach (TableBlock block in Data.Blocks)
            {
                SetBlockType(block);
                block.SetVisibleIfPossible();
            }
        }

        void SetBlockType(TableBlock block)
        {
            switch (ViewerType)
            {
                case ViewerType.System:
                    SystemParser.SetObjectType(block, Archetype);
                    break;
                case ViewerType.Universe:
                    SystemParser.SetUniverseObjectType(block);
                    break;
                case ViewerType.SolarArchetype:
                    SystemParser.SetSolarArchetypeObjectType(block);
                    break;
                case ViewerType.ModelPreview:
                    SystemParser.SetModelPreviewObjectType(block);
                    break;
            }
        }

        void SetViewerType()
        {
            if (Data.TemplateIndex == Helper.Template.Data.SystemFile)
            {
                ViewerType = ViewerType.System;
            }
            else if (Data.TemplateIndex == Helper.Template.Data.UniverseFile)
            {
                ViewerType = ViewerType.Universe;
            }
            else if (Data.TemplateIndex == Helper.Template.Data.SolarArchetypeFile)
            {
                ViewerType = ViewerType.SolarArchetype;
            }
            else if (Data.TemplateIndex == Helper.Template.Data.AsteroidArchetypeFile ||
                     Data.TemplateIndex == Helper.Template.Data.ShipArchetypeFile ||
                     Data.TemplateIndex == Helper.Template.Data.EquipmentFile ||
                     Data.TemplateIndex == Helper.Template.Data.EffectExplosionsFile)
            {
                ViewerType = ViewerType.ModelPreview;
            }
            else
            {
                ViewerType = ViewerType.None;
            }
        }

        public void ShowData()
        {
            SetViewerType();
            switch (ViewerType)
            {
                case ViewerType.SolarArchetype:
                case ViewerType.ModelPreview:
                    DataPath = Helper.Template.Data.GetDataPath(File, Helper.Template.Data.SolarArchetypeFile);
                    SetAllBlockTypes();
                    break;
                case ViewerType.System:
                case ViewerType.Universe:
                    LoadArchetypes();
                    break;
            }

#if DEBUG
            Stopwatch st = new Stopwatch();
            st.Start();
#endif
            //sort by type and name
            Data.Blocks.Sort();
            contentView.ItemsSource = Data.Blocks;

            //add block types to add menu
            for (int i = 0; i < Helper.Template.Data.Files[Data.TemplateIndex].Blocks.Count; ++i)
            {
                AddInfo info = new AddInfo
                {
                    Index = i,
                    Text = Helper.Template.Data.Files[Data.TemplateIndex].Blocks.Values[i].Name
                };

                MenuItem addItem = new MenuItem
                {
                    Header = info.Text,
                    CommandParameter = info,
                    Command = CustomCommands.Add
                };
                mnuAdd.Items.Add(addItem);
            }

#if DEBUG
            st.Stop();
            Debug.WriteLine("display " + contentView.Items.Count + " data: " + st.ElapsedMilliseconds + "ms");
#endif
        }


        void contentView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            OnSelectionChanged(GetSelectedBlocks(), Data.TemplateIndex);
            OnContentChanged(this);
        }

        void Save(string file)
        {
            FileManager fileManager = new FileManager(file, _isBINI)
                {
                    WriteSpaces = Helper.Settings.Data.Data.General.FormattingSpaces,
                    WriteEmptyLine = Helper.Settings.Data.Data.General.FormattingEmptyLine
                };
            fileManager.Write(Data.GetEditorData());

            SetAsSaved();

            try
            {
                SetFile(file);
            }
            catch (Exception ex)
            {
                Helper.Exceptions.Show(ex);
            }
        }

        void SetFile(string file)
        {
            File = file;

            string title = GetTitle();
            if (_undoManager.IsModified())
            {
                title += "*";
            }

            Title = title;

            OnDocumentChanged(this);
        }

        void SetAsSaved()
        {
            if (_undoManager.IsModified())
            {
                _undoManager.SetAsSaved();

                //set objects in listview as unmodified
                foreach (TableBlock tableData in Data.Blocks)
                {
                    if (tableData.Modified == TableModified.Changed ||
                        tableData.Modified == TableModified.ChangedAdded)
                    {
                        tableData.Modified = TableModified.ChangedSaved;
                    }
                }
            }
        }

        bool CancelClose()
        {
            if (_undoManager.IsModified())
            {
                MessageBoxResult dialogResult = MessageBox.Show(String.Format(Strings.FileCloseSave, GetTitle()), Helper.Assembly.Name, MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
                if (dialogResult == MessageBoxResult.Cancel)
                {
                    return true;
                }
                if (dialogResult == MessageBoxResult.Yes)
                {
                    Save();
                }
            }

            return false;
        }

        void AddBlocks(ObservableCollection<TableBlock> blocks, int undoBlock, bool undo)
        {
            ObservableCollection<TableBlock> selectedData = new ObservableCollection<TableBlock>();
            for (int i = 0; i < blocks.Count; i++)
            {
                Template.Block templateBlock = Helper.Template.Data.Files[Data.TemplateIndex].Blocks.Values[blocks[i].Block.TemplateIndex];
                TableBlock tableBlock = blocks[i];

                //set block to be modified except in undo mode
                if (!undo)
                {
                    tableBlock.Modified = TableModified.ChangedAdded;
                }

                //set archetype of block and make visible if possible
                if (tableBlock.Archetype == null)
                {
                    SetBlockType(tableBlock);
                    tableBlock.SetVisibleIfPossible();
                }

                bool existSingle = false;

                //check if block already exists if it is a single block
                if (!templateBlock.Multiple)
                {
                    for (int j = 0; j < Data.Blocks.Count; ++j)
                    {
                        //block already exists
                        if (Data.Blocks[j].Block.TemplateIndex == blocks[i].Block.TemplateIndex)
                        {
                            tableBlock.Index = Data.Blocks[j].Index;
                            tableBlock.Id = Data.Blocks[j].Id;

                            //overwrite data if we add blocks which are single then they are overwritten which means they have to be changed to edit in the undo history
                            _undoManager.CurrentData[undoBlock] = new ChangedData
                                {
                                    Type = ChangedType.Edit,
                                    OldBlocks = new ObservableCollection<TableBlock>
                                        {
                                            Data.Blocks[j]
                                        },
                                    NewBlocks = new ObservableCollection<TableBlock>
                                        {
                                            tableBlock
                                        },
                                };

                            //overwrite block
                            Data.Blocks[j] = tableBlock;
                            existSingle = true;

                            break;
                        }
                    }
                }

                if (!existSingle)
                {
                    if (blocks[i].Index >= Data.Blocks.Count)
                    {
                        Data.Blocks.Add(blocks[i]);
                    }
                    else
                    {
                        Data.Blocks.Insert(blocks[i].Index, blocks[i]);
                    }
                }

                selectedData.Add(tableBlock);
            }

            Data.Blocks.Sort();

            SelectBlocks(selectedData);
            EnsureSelectionVisible();
        }

        void AddNewBlock(string blockName, int templateIndex)
        {
            Template.Block templateBlock = Helper.Template.Data.Files[Data.TemplateIndex].Blocks.Values[templateIndex];

            //add options to new block
            EditorINIBlock editorBlock = new EditorINIBlock(blockName, templateIndex);
            for (int i = 0; i < templateBlock.Options.Count; ++i)
            {
                Template.Option option = templateBlock.Options[i];
                editorBlock.Options.Add(new EditorINIOption(option.Name, i));

                if (templateBlock.Identifier != null && templateBlock.Identifier.Equals(editorBlock.Options[editorBlock.Options.Count - 1].Name, StringComparison.OrdinalIgnoreCase))
                {
                    editorBlock.MainOptionIndex = editorBlock.Options.Count - 1;
                    editorBlock.Options[editorBlock.Options.Count - 1].Values.Add(new EditorINIEntry(blockName));
                }
            }

            //add actual block
            _undoManager.Execute(new ChangedData
                {
                    NewBlocks = new ObservableCollection<TableBlock>
                        {
                            new TableBlock(GetNewBlockId(), Data.MaxId++, editorBlock, Data.TemplateIndex)
                        },
                    Type = ChangedType.Add
                });
        }

        void UnselectAllBlocks()
        {
            foreach (TableBlock block in contentView.SelectedItems)
            {
                block.IsSelected = false;
            }
        }

        void SelectBlocks(IList blocks)
        {
            UnselectAllBlocks();

            foreach (TableBlock block in blocks)
            {
                block.IsSelected = true;
            }
        }

        void SelectBlock(TableBlock block)
        {
            UnselectAllBlocks();

            block.IsSelected = true;
        }

        void ToggleBlockSelection(TableBlock block)
        {
            block.IsSelected = !block.IsSelected;
        }

        public ObservableCollection<TableBlock> GetSelectedBlocks()
        {
            if (contentView.SelectedItems.Count == 0)
            {
                return null;
            }

            ObservableCollection<TableBlock> blocks = new ObservableCollection<TableBlock>();
            foreach (TableBlock tableData in contentView.SelectedItems)
            {
                blocks.Add(tableData);
            }

            return blocks;
        }

        public void SetBlocks(PropertyBlock[] blocks)
        {
            ObservableCollection<TableBlock> newBlocks = new ObservableCollection<TableBlock>();
            ObservableCollection<TableBlock> oldBlocks = new ObservableCollection<TableBlock>();

            for (int i = 0; i < blocks.Length; ++i)
            {
                TableBlock oldBlock = (TableBlock)contentView.SelectedItems[i];
                TableBlock newBlock = ObjectClone.Clone(oldBlock);

                oldBlocks.Add(oldBlock);
                newBlocks.Add(newBlock);

                for (int j = 0; j < blocks[i].Count; ++j)
                {
                    List<EditorINIEntry> options = newBlock.Block.Options[j].Values;

                    if (blocks[i][j].Value is PropertySubOptions)
                    {
                        options.Clear();

                        //loop all sub values in the sub value collection
                        foreach (PropertyOption value in (PropertySubOptions)blocks[i][j].Value)
                        {
                            string text = ((string)value.Value).Trim();
                            if (text.Length != 0)
                            {
                                if (text.Contains(Environment.NewLine))
                                {
                                    string[] lines = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                                    List<object> subOptions = new List<object>();
                                    for (int k = 1; k < lines.Length; ++k)
                                    {
                                        subOptions.Add(lines[k].Trim());
                                    }

                                    options.Add(new EditorINIEntry(lines[0], subOptions));
                                }
                                else
                                {
                                    options.Add(new EditorINIEntry(text));
                                }
                            }
                        }
                    }
                    else
                    {
                        string text = ((string)blocks[i][j].Value).Trim();
                        if (text.Length != 0)
                        {
                            if (options.Count > 0)
                            {
                                //check if value is different
                                if (options[0].Value.ToString() != text)
                                {
                                    options[0].Value = text;
                                }
                            }
                            else
                            {
                                options.Add(new EditorINIEntry(text));
                            }
                        }
                        else
                        {
                            options.Clear();
                        }

                        //change data in listview
                        if (newBlock.Block.MainOptionIndex == j)
                        {
                            newBlock.Name = text;
                        }
                    }
                }

                // update block object type
                SetBlockType(newBlock);

                // make block visible if it can be made visible now
                if (oldBlock.ObjectType == ContentType.None)
                {
                    newBlock.SetVisibleIfPossible();
                }

                // mark block as modified
                newBlock.SetModifiedChanged();
            }

            SetBlocks(newBlocks, oldBlocks);
        }

        public void SetBlocks(ObservableCollection<TableBlock> newBlocks, ObservableCollection<TableBlock> oldBlocks)
        {
            _undoManager.Execute(new ChangedData
                {
                    NewBlocks = newBlocks,
                    OldBlocks = oldBlocks,
                    Type = ChangedType.Edit
                });
        }

        void ChangeBlocks(ObservableCollection<TableBlock> newBlocks, ObservableCollection<TableBlock> oldBlocks)
        {
            for (int i = 0; i < oldBlocks.Count; ++i)
            {
                int index = Data.Blocks.IndexOf(oldBlocks[i]);
                Data.Blocks[index] = newBlocks[i];
            }

            Data.Blocks.Sort();

            //select objects which were selected before
            SelectBlocks(newBlocks);
            EnsureSelectionVisible();
        }

        void MoveBlocks(ObservableCollection<TableBlock> newBlocks, ObservableCollection<TableBlock> oldBlocks)
        {
            //remove all moved blocks first because otherwise inserted index would be wrong
            List<TableBlock> blocks = new List<TableBlock>();
            for (int i = oldBlocks.Count - 1; i >= 0; i--)
            {
                blocks.Add(Data.Blocks[oldBlocks[i].Index]);
                Data.Blocks.RemoveAt(oldBlocks[i].Index);
            }

            //insert blocks at new position
            for (int i = 0; i < oldBlocks.Count; ++i)
            {
                Data.Blocks.Insert(newBlocks[i].Index, blocks[oldBlocks.Count - i - 1]);
            }

            Data.RefreshIndices(Math.Min(oldBlocks[0].Index, newBlocks[0].Index));
            //select objects which were selected before
            SelectBlocks(blocks);
            EnsureSelectionVisible();
        }

        void DeleteBlocks(ObservableCollection<TableBlock> blocks)
        {
            IList selection = contentView.SelectedItems;

            foreach (TableBlock tableBlock in blocks)
            {
                Data.Blocks.Remove(tableBlock);
            }

            //select objects which were selected before
            SelectBlocks(selection);
            EnsureSelectionVisible();
        }

        void DeleteSelectedBlocks()
        {
            ObservableCollection<TableBlock> blocks = new ObservableCollection<TableBlock>();

            foreach (TableBlock block in Data.Blocks)
            {
                blocks.Add(block);
            }

            _undoManager.Execute(new ChangedData
                {
                    NewBlocks = blocks,
                    Type = ChangedType.Delete
                });
        }

        void EnsureSelectionVisible()
        {
            if (contentView.SelectedItems.Count > 0)
            {
                contentView.ScrollIntoView(contentView.SelectedItems[contentView.SelectedItems.Count - 1]);

                if (contentView.SelectedItems.Count > 1)
                {
                    contentView.ScrollIntoView(contentView.SelectedItems[0]);
                }
            }
        }

        void DocumentContent_Closing(object sender, CancelEventArgs e)
        {
            e.Cancel = CancelClose();
        }

        void contentContextMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            SetContextMenu();
        }

        void SetContextMenu()
        {
            Visibility value = Visibility.Collapsed;
            if (contentView.SelectedItems.Count > 0)
            {
                value = Visibility.Visible;
            }

            mnuDeleteSeperator.Visibility = value;
            mnuDelete.Visibility = value;
            mnuDelete.IsEnabled = contentView.SelectedItems.Count > 0;
        }

        void OpenAddMenu(object sender, RoutedEventArgs e)
        {
            contentContextMenu.IsOpen = true;
            mnuAdd.IsSubmenuOpen = true;
        }

        void mnuDelete_Click(object sender, RoutedEventArgs e)
        {
            DeleteSelectedBlocks();
        }

        void mnuAddItem_Click(object sender, ExecutedRoutedEventArgs e)
        {
            AddInfo info = e.Parameter as AddInfo;
            AddNewBlock(info.Text, info.Index);
        }

        int GetNewBlockId()
        {
            //add new block under selected one if it exists otherwise at the end
            if (contentView.SelectedItems.Count > 0)
            {
                return ((TableBlock)contentView.SelectedItems[contentView.SelectedItems.Count - 1]).Id + 1;
            }

            return Data.Blocks.Count;
        }

        #region ContentInterface Members

        public void SelectAll()
        {
            contentView.SelectAll();
        }

        public bool CanSave()
        {
            return true;
        }

        public bool CanCopy()
        {
            return contentView.SelectedItems.Count > 0;
        }

        public bool CanCut()
        {
            return contentView.SelectedItems.Count > 0;
        }

        public bool CanPaste()
        {
            return Clipboard.CanPaste(typeof(EditorINIData));
        }

        public bool CanAdd()
        {
            return true;
        }

        public bool CanDelete()
        {
            return contentView.SelectedItems.Count > 0;
        }

        public bool CanSelectAll()
        {
            return true;
        }

        public void Save()
        {
            if (File.Length == 0)
            {
                SaveAs();
            }
            else
            {
                Save(File);
            }
        }

        public void SaveAs()
        {
            SaveFileDialog saveDialog = new SaveFileDialog
                {
                    Filter = Strings.FileDialogFilter
                };
            if (saveDialog.ShowDialog().Value)
            {
                Save(saveDialog.FileName);
            }
        }

        public void Add(int index)
        {
            MenuItem item = mnuAdd.Items[index] as MenuItem;
            AddInfo info = item.CommandParameter as AddInfo;
            AddNewBlock(info.Text, info.Index);
        }

        public void Delete()
        {
            DeleteSelectedBlocks();
        }

        string GetFileName()
        {
            if (File.Length == 0)
            {
                return File;
            }

            return Path.GetFileName(File);
        }

        public string GetTitle()
        {
            return File.Length == 0 ? Strings.FileEditorNewFile : Path.GetFileName(File);
        }

        public void Copy()
        {
            EditorINIData data = new EditorINIData(Data.TemplateIndex);
            foreach (TableBlock tableData in contentView.SelectedItems)
            {
                data.Blocks.Add(tableData.Block);
            }

            Clipboard.Copy(data, typeof(EditorINIData));

            OnContentChanged(this);
        }

        public void Cut()
        {
            Copy();
            DeleteSelectedBlocks();
        }

        public void Paste()
        {
            EditorINIData editorData = (EditorINIData)Clipboard.Paste(typeof(EditorINIData));

            if (editorData.TemplateIndex == Data.TemplateIndex)
            {
                int id = GetNewBlockId();

                ObservableCollection<TableBlock> blocks = new ObservableCollection<TableBlock>();
                for (int i = 0; i < editorData.Blocks.Count; ++i)
                {
                    blocks.Add(new TableBlock(id + i, Data.MaxId++, editorData.Blocks[i], Data.TemplateIndex));
                }

                _undoManager.Execute(new ChangedData
                    {
                        NewBlocks = blocks,
                        Type = ChangedType.Add
                    });
            }
        }

        public bool UseDocument()
        {
            return false;
        }

        public bool CanUndo()
        {
            return _undoManager.CanUndo();
        }

        public bool CanRedo()
        {
            return _undoManager.CanRedo();
        }

        public void Undo()
        {
            _undoManager.Undo(1);
        }

        public void Redo()
        {
            _undoManager.Redo(1);
        }

        public bool CanDisplay3DViewer()
        {
            return ViewerType != ViewerType.None;
        }

        public bool CanManipulatePosition()
        {
            return ViewerType == ViewerType.System || ViewerType == ViewerType.Universe;
        }

        public bool CanManipulateRotationScale()
        {
            return ViewerType == ViewerType.System;
        }

        void ExecuteDataChanged(ChangedData data, int undoBlock, bool undo)
        {
            switch (data.Type)
            {
                case ChangedType.Add:
                    AddBlocks(data.NewBlocks, undoBlock, undo);
                    break;
                case ChangedType.Delete:
                    DeleteBlocks(data.NewBlocks);
                    break;
                case ChangedType.Edit:
                    ChangeBlocks(data.NewBlocks, data.OldBlocks);
                    break;
                case ChangedType.Move:
                    MoveBlocks(data.NewBlocks, data.OldBlocks);
                    break;
            }

            OnDataChanged(data);
        }

        void UndoManager_DataChanged(List<ChangedData> data, bool undo)
        {
            for (int i = 0; i < data.Count; ++i)
            {
                ExecuteDataChanged(undo ? data[i].GetUndoData() : data[i], i, undo);
            }

            SetFile(File);
            //OnDocumentChanged(this); is already called in SetFile
        }

        public void Select(TableBlock block, bool toggle)
        {
            if (toggle)
            {
                ToggleBlockSelection(block);
            }
            else
            {
                SelectBlock(block);
            }

            EnsureSelectionVisible();
        }

        public void HideShowSelected()
        {
            if (contentView.SelectedItems.Count == 0)
            {
                return;
            }

            bool visibility = !((TableBlock)contentView.SelectedItems[0]).Visibility;

            foreach (TableBlock block in contentView.SelectedItems)
            {
                if (block.ObjectType != ContentType.None && block.Visibility != visibility)
                {
                    block.Visibility = visibility;
                    OnDataVisibilityChanged(block);
                }
            }
        }

        public bool CanChangeVisibility(bool rightNow)
        {
            bool correctFileType = ViewerType == ViewerType.System;
            if (rightNow)
            {
                return correctFileType && contentView.SelectedItems.Count > 0;
            }

            return correctFileType;
        }

        public bool CanFocusSelected(bool rightNow)
        {
            bool correctFileType = ViewerType != ViewerType.None;
            if (rightNow)
            {
                return correctFileType && contentView.SelectedItems.Count > 0;
            }

            return correctFileType;
        }

        public bool CanTrackSelected(bool rightNow)
        {
            bool correctFileType = ViewerType == ViewerType.System;
            if (rightNow)
            {
                return correctFileType && contentView.SelectedItems.Count > 0;
            }

            return correctFileType;
        }

        public void ChangeVisibility()
        {
            HideShowSelected();
        }

        public AddInfo[] MultipleAddDropDown()
        {
            AddInfo[] infos = new AddInfo[mnuAdd.Items.Count];
            for (int i = 0; i < mnuAdd.Items.Count; i++)
            {
                infos[i] = (mnuAdd.Items[i] as MenuItem).CommandParameter as AddInfo;
            }

            return infos;
        }

        #endregion
    }
}
